#include "DrawTest.h"

#include "..\..\Rendering\canvas\Image.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

DrawTest::DrawTest() {
	const int count = 16;
	DisplayObject* displayObjects[count];

	displayObjects[0] = new CircleDraw();
	displayObjects[1] = CreateCircleShape();
	displayObjects[2] = new RectangleDraw();
	displayObjects[3] = CreateRectangleShape();
	displayObjects[4] = new LineDraw();
	displayObjects[5] = CreateLineShape();
	displayObjects[6] = new PolygonDraw();
	displayObjects[7] = CreatePolygonShape();
	displayObjects[8] = new BezierDraw();
	displayObjects[9] = CreateBezierShape();
	displayObjects[10] = new ImageDraw();
	displayObjects[11] = CreateImageShape();
	displayObjects[12] = new TextDraw();
	displayObjects[13] = CreateTextShape();
	displayObjects[14] = new LinearGradientDraw();
	displayObjects[15] = CreateLinearGradientShape();
	

	for(int i = 0; i < count; i++) {
		DisplayObject* displayObject = displayObjects[i];
		if(displayObject == 0) continue; 

		int step = (int)(i%2);
		displayObject->_x = (i-step) * 60;
		displayObject->_y = 20 + (step * 150);
		this->addChild(displayObject);
	}
}

DrawTest::~DrawTest() {

}

bool CircleDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetStrokeStyle(1, 0, 0);
	ctx->SetFillStyle(0, 0, 1);

	ctx->lineWidth = 2;

	ctx->beginPath();
	ctx->arc(0, 0, 60, 0, M_PI*2, true); 
	ctx->closePath();

	ctx->fill();
	ctx->stroke();
	
	return true;
}

Shape* CreateCircleShape() {
	Shape* circleShape = new Shape();

    circleShape->graphics.setStrokeStyle(1, 0, 0);
    circleShape->graphics.setFillStyle(0, 0, 1);

    circleShape->graphics.setLineWidth(2);

    circleShape->graphics.beginPath();
    circleShape->graphics.arc(0, 0, 60, 0, M_PI*2, true);
    circleShape->graphics.closePath();

    circleShape->graphics.fill();
    circleShape->graphics.stroke();

	return circleShape;
}

bool RectangleDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetStrokeStyle(1, 0, 0);
	ctx->SetFillStyle(0, 0, 1);

	ctx->lineWidth = 2;

	ctx->rect(0, 0, 150, 70);

	ctx->fill();
	ctx->stroke();
	
	return true;
}

Shape* CreateRectangleShape() {
    Shape* rectShape= new Shape();

    rectShape->graphics.setStrokeStyle(1, 0, 0);
    rectShape->graphics.setFillStyle(0, 0, 1);

    rectShape->graphics.setLineWidth(2);

    rectShape->graphics.rect(0, 0, 150, 70);

    rectShape->graphics.fill();
    rectShape->graphics.stroke();

	return rectShape;
}

bool LineDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetStrokeStyle(1, 0, 0);

	ctx->lineWidth = 2;

	ctx->beginPath();

	ctx->moveTo(0, 0);
	ctx->lineTo(100, 0);
	ctx->lineTo(40, 100);
	ctx->lineTo(0, 70);

	ctx->stroke();

	return true;
}

Shape* CreateLineShape() {
    Shape* lineShape = new Shape();

    lineShape->graphics.setStrokeStyle(1, 0, 0);

    lineShape->graphics.setLineWidth(2);

    lineShape->graphics.beginPath();

    lineShape->graphics.moveTo(0, 0);
    lineShape->graphics.lineTo(100, 0);
    lineShape->graphics.lineTo(40, 100);
    lineShape->graphics.lineTo(0, 70);

    lineShape->graphics.stroke();

    return lineShape;
}

bool PolygonDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetStrokeStyle(1, 0, 0);
	ctx->SetFillStyle(0, 0, 1);

	ctx->lineWidth = 2;

	ctx->beginPath();

	ctx->moveTo(0, 0);
	ctx->lineTo(100, 0);
	ctx->lineTo(40, 100);
	ctx->lineTo(0, 70);

	ctx->closePath();

	ctx->fill();
	ctx->stroke();

	return true;
}

Shape* CreatePolygonShape() {
	Shape* polygonShape = new Shape();

    polygonShape->graphics.setStrokeStyle(1, 0, 0);

    polygonShape->graphics.setLineWidth(2);

    polygonShape->graphics.beginPath();

    polygonShape->graphics.moveTo(0, 0);
    polygonShape->graphics.lineTo(100, 0);
    polygonShape->graphics.lineTo(40, 100);
    polygonShape->graphics.lineTo(0, 70);

    polygonShape->graphics.closePath();

    polygonShape->graphics.fill();
    polygonShape->graphics.stroke();

    return polygonShape;
}

bool BezierDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetStrokeStyle(1, 0, 0);

	ctx->lineWidth = 2;

	ctx->beginPath();

	ctx->moveTo(0, 0);
	ctx->bezierCurveTo(30, 70, 100, 150, 50, 20);

	ctx->stroke();

	return true;
}

Shape* CreateBezierShape() {
	Shape* bezierShape = new Shape();

    bezierShape->graphics.setStrokeStyle(1, 0, 0);

    bezierShape->graphics.setLineWidth(2);

    bezierShape->graphics.beginPath();

    bezierShape->graphics.moveTo(0, 0);
	bezierShape->graphics.bezierCurveTo(30, 70, 100, 150, 50, 20);

    bezierShape->graphics.stroke();

    return bezierShape;
}

bool ImageDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	//Image* image = new Image(L"..\..\Data\Textures\EyeOfHorus_128.png");

	//ctx->drawImage(image, 0, 0);

	return true;
}

Shape* CreateImageShape() {
	//Shape* imageShape = new Shape();

	//imageShape->graphics.image

	return 0; //textShape;
}

bool TextDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->SetFillStyle(0, 0, 1);

	ctx->fillText("Hello World", 0, 0);

	return true;
}

Shape* CreateTextShape() {
	Shape* textShape = new Shape();

	textShape->graphics.fillText("Hello World", 0, 0);

	return textShape;
}

bool LinearGradientDraw::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
	ctx->rect(0, 0, 150, 70);
	
	CanvasGradient canvasGradient = ctx->createLinearGradient(0, 0, 150, 0);
	canvasGradient.addColorStop(0, Color::BLUE);
	canvasGradient.addColorStop(1, Color::GREEN);
	canvasGradient.addColorStop(0.5, Color::RED);
	
	ctx->SetFillStyle(canvasGradient);

	CanvasGradient canvasGradient2 = ctx->createLinearGradient(0, 0, 150, 0);
	canvasGradient2.addColorStop(0, Color::RED);
	canvasGradient2.addColorStop(1, Color::BLUE);
	
	ctx->SetStrokeStyle(canvasGradient2);

	ctx->fill();
	ctx->stroke();

	return true;
}

Shape* CreateLinearGradientShape() {
	Shape* linearGradientShape = new Shape();

	linearGradientShape->graphics.fillText("Hello World", 0, 0);

	return linearGradientShape;
}